package com.hulk.dryad.web.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.ms.sequence.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.hulk.dryad.common.annotation.Idempotent;
import com.hulk.dryad.common.annotation.PrintlnLog;
import com.hulk.dryad.common.annotation.RespData;
import com.hulk.dryad.common.constant.CacheConstants;
import com.hulk.dryad.common.constant.CommonConstants;
import com.hulk.dryad.common.constant.enums.*;
import com.hulk.dryad.common.exception.WebRteException;

import com.hulk.dryad.common.util.IDWorkerRadix;
import com.hulk.dryad.common.util.PasswordEncoderFactoriesUtil;
import com.hulk.dryad.common.util.SaltGenerator;
import com.hulk.dryad.manage.provider.transaction.CustomerTransaction;
import com.hulk.dryad.persistence.entity.CustomerLoginInfo;
import com.hulk.dryad.persistence.entity.CustomerOperator;
import com.hulk.dryad.manage.provider.service.impl.CustomerLoginInfoServiceImpl;
import com.hulk.dryad.web.api.vo.CustomerLogoutReqVO;
import com.hulk.dryad.web.api.vo.CustomerRegisterReqVO;
import com.hulk.dryad.web.api.vo.CustomerRegisterRespVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.time.LocalDateTime;

/**
 * @author lqx
 */
@Api(value = " customer", tags = "用户模块")
@ApiSort(3)
@Slf4j
@RestController
@RequestMapping("/customer")
@RequiredArgsConstructor
public class CustomerController {

    private final CustomerLoginInfoServiceImpl customerLoginInfoServiceImpl;
    private final CustomerTransaction customerTransaction;
    private final CacheManager cacheManager;

    /**
     * <post>用户注册</post>
     *
     * @param reqDto 用户注册
     * @return R
     */
    @ApiOperation(value = "register", notes = "用户注册")
    @ApiOperationSupport(order = 0)
    @PrintlnLog
    @Idempotent
    @RespData
    @PostMapping("/register")
    public CustomerRegisterRespVO register(@RequestBody @Valid CustomerRegisterReqVO reqDto) {
        String workId = IdWorker.getId() + "";
        log.info("workId:[{}] 用户注册,入参:[{}]", workId, reqDto);

		CustomerLoginInfo customer = customerLoginInfoServiceImpl.getOne(Wrappers.<CustomerLoginInfo>lambdaQuery()
				.eq(CustomerLoginInfo::getLoginNo, reqDto.getLoginNo()).eq(CustomerLoginInfo::getLoginType,LoginType.PWD.getType()));
		if (null != customer) {
			throw new WebRteException(BEC.E_2016);
		}

		String operatorNo = IDWorkerRadix.getDTMId();
		/*密码加密盐*/
		String passSalt = SaltGenerator.generateSalt();
		String loginPassword = reqDto.getLoginPwd();//// TODO: 2020/10/13  此处应为解密请求登陆密码后的结果，加解密方式自定义

		CustomerLoginInfo loginInfo = new CustomerLoginInfo();
		loginInfo.setId(IdWorker.getId());
		loginInfo.setOperatorNo(operatorNo);
		loginInfo.setLoginNo(reqDto.getLoginNo());
		loginInfo.setLoginSignChannel(reqDto.getChannel());
		loginInfo.setLoginType(LoginType.PWD.getType());
		loginInfo.setLoginStatus(CustomerLoginStatus.NORMAL.getType());
		loginInfo.setCreatedTime(LocalDateTime.now());
		loginInfo.setCreatedBy(CommonConstants.DEFUAULT_CREATER);

		CustomerOperator operatorInfo = new CustomerOperator();
		operatorInfo.setId(IdWorker.getId());
		operatorInfo.setOperatorNo(operatorNo);
		operatorInfo.setOperatorName(reqDto.getName());
		operatorInfo.setOperatorLvl(OperatorLevel.NOVICE.getType());
		operatorInfo.setNickName(reqDto.getNickName());
		operatorInfo.setLoginPwd(PasswordEncoderFactoriesUtil.encode(loginPassword).replace("{bcrypt}", ""));
		operatorInfo.setLoginSalt(passSalt);
		operatorInfo.setRealnameStatus(YNFlag.N.getCode());
		operatorInfo.setLoginRightRange(OperatorLoginRange.ALL.getType());
		operatorInfo.setIdentity(null);
		operatorInfo.setOperatorStatus(OperatorStatus.NORMAL.getType());
		operatorInfo.setDataSourceType(OperatorSource.NORMAL.getType());
		operatorInfo.setPwdCreateType(PwdCreateType.CUSTOMER.getType());
		operatorInfo.setCreatedBy(CommonConstants.DEFUAULT_CREATER);
		operatorInfo.setCreatedTime(LocalDateTime.now());
		operatorInfo.setRsv1(RandomStringUtils.randomAlphabetic(32));
		customerTransaction.insertCustomerRelates(workId, loginInfo, operatorInfo);

		CustomerRegisterRespVO	respDto = new CustomerRegisterRespVO();
		respDto.setLoginNo(reqDto.getLoginNo());
		respDto.setEncryptKey(operatorInfo.getRsv1());
		respDto.setFinishTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));

        return respDto;
    }




    /**
     * logout
     *
     * @param reqVo reqVo
     * @return R
     */
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "logout", notes = "用户登出")
    @PrintlnLog
    @RespData
    @PostMapping("/logout")
    public void logout(@RequestBody @Valid CustomerLogoutReqVO reqVo) {
        String workId = IdWorker.getId() + "";
        log.info("workId:[{}] 用户登出,入参:[{}]", workId, reqVo);
		CustomerLoginInfo customer = customerLoginInfoServiceImpl.getOne(Wrappers.<CustomerLoginInfo>lambdaQuery()
				.eq(CustomerLoginInfo::getLoginNo, reqVo.getLoginNo()).eq(CustomerLoginInfo::getLoginType,reqVo.getLoginType()));
		if (null == customer) {
			throw new WebRteException(BEC.E_2015);
		}
		//清除登陆记录
		clearLoginNoCache(reqVo.getLoginNo());

    }

    /**
     * 清除登录缓存
     *
     * @param loginNo 登录号
     */
    private void clearLoginNoCache(String loginNo) {
        Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
        if (null != cache) {
            if (null != cache.get(loginNo)) {
                cache.evict(loginNo);
            }
        }
    }
}